<?php
/*
 * 接收包返回包接口
* @author 张云江
*/
abstract class PackBase
{

	public $op_type;
	public $task_id;
	public $sid;
	public $user_id;
	public $current_dt;
	/**
	 * 输出信息类
	 * @var ModelOutPutInfo
	 */
	public $outModel; //输出信息类
	public $c_type;      //0=ios的客户端类型,1=android
	public $c_ver;      //客户端版本号
	public $symbol; 	//分页参数
	public $pid;  		//产品ID
	public $gender;
	private $delParams = array(); //需要删除的字段，一般用于版本控制

	//客户端必带参数
	public $base_required = array(
		'op_type'
	);

	function __construct($pack)
	{
		//将客户端上传的值赋值，通过$this->var 直接调用
		foreach ($pack as $key => $val) {
			$this->$key = $val;
		}
		$this->outModel = ModelOutPutInfo::getInstance();
		$this->setPack($pack); //不要随便改变setPack和args_validate函数调用顺序
		$this->args_validate($this->base_required, $pack);
		$this->pid = $pack->pid;
		$this->user_id = $pack->user_id;
		$this->sid = $pack->sid;
		$this->op_type = $pack->op_type;
		$this->task_id = $pack->task_id;
		$this->c_type = $pack->c_type;
		$this->c_ver = $pack->c_ver;
		$this->current_dt = $this->getTimestamp();
		$this->symbol = empty($this->symbol) ? 0 : $this->symbol; //100只是随机数，防止当前传入数据，立即拉取，
	}

	function __destruct()
	{
	}

	private function getTimestamp()
	{
		return time() . substr(microtime(), 2, 6);
	}

	public function getCurrentDay()
	{
		return date("Y-m-d");
	}

	public function getCurrentTime()
	{
		return date("Y-m-d H:i:s");
	}

	abstract function setPack($pack);
	/**
	 * 设置客户端必传参数
	 * @return array
	 */
	abstract function setRequiredParms();
	/**
	 * 接口入口程序
	 *
	 * 你可以再这儿通过调用不同方法实现不同功能
	 */
	abstract function run();

	/**
	 * 接口参数校验，传入的参数包括全局参数和接口参数，
	 * @param $required     校验参数
	 * @param $input          传入参数
	 * @return array            丢失的参数
	 */
	private function args_validate($required, $input)
	{
		$sub_required = $this->setRequiredParms();
		$sub_required = is_array($sub_required) ? $sub_required : array();
		$required = array_merge($required, $sub_required);
		foreach ($required as $k => $v) { //删除需要临时设置不用上传的参数
			if (in_array($v, $this->delParams)) {
				unset($required[$k]);
			}
		}
		$missing_keys = array();
		foreach ($required as $key => $val) {
			if (!array_key_exists($val, $input)) {
				array_push($missing_keys, $val);
			}
		}
		if (count($missing_keys) > 0) {
			$this->outModel->AddOutInfo("code", "-998");
			$this->outModel->AddOutInfo("missing_args", $missing_keys);
			echo $this->outModel->outPutJson();
			exit;
		}
	}

	/**
	 * 删除已经设置的必传参数,
	 * 只要设置一次 则该接口当次会话不会再要求客户端上传该参数
	 * @param array $params 可以是一个字符也可以是数组
	 */
	public function delRequiredParams($params)
	{
		if (is_array($params)) {
			$this->delParams = array_merge($params, $this->delParams);
		} else {
			array_push($this->delParams, $params);
		}
	}
}
